{
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "nQ_Y_RV0kyUC"
      },
      "source": [
        "Copyright 2021 Google LLC\n",
        "\n",
        "Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except in compliance with the License. You may obtain a copy of the License at\n",
        "\n",
        "https://www.apache.org/licenses/LICENSE-2.0\n",
        "\n",
        "Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "7xX60bTWkwrQ"
      },
      "outputs": [],
      "source": [
        "import sklearn\n",
        "import numpy as np\n",
        "from sklearn import svm\n",
        "from tensorflow.keras.datasets import fashion_mnist\n",
        "\n",
        "(trn_x, trn_y), (tst_x, tst_y) = fashion_mnist.load_data()\n",
        "twoclass_inds = np.where(trn_y\u003c=1)[0]\n",
        "trn_x, trn_y = trn_x[twoclass_inds], trn_y[twoclass_inds]\n",
        "trn_x = trn_x.reshape((trn_x.shape[0], -1))/255.0 - .5\n",
        "trn_ct, pois_ct = 2000, 200\n",
        "print(trn_x.shape, trn_y.shape)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "OBLfhmvqm1sG"
      },
      "source": [
        "# FMNIST clean"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "y8kErmldm5dP"
      },
      "outputs": [],
      "source": [
        "# linear\n",
        "print(\"Total Samples: {}\".format(trn_ct))\n",
        "total_sv = []\n",
        "for _ in range(5):\n",
        "  fm_trn_inds = np.random.choice(trn_x.shape[0], trn_ct, replace=False)\n",
        "  fm_trn_x, fm_trn_y = trn_x[fm_trn_inds], trn_y[fm_trn_inds]\n",
        "  clean_linear = svm.SVC(kernel='linear')\n",
        "  clean_linear.fit(fm_trn_x, fm_trn_y)\n",
        "  duals = np.array(clean_linear.dual_coef_)\n",
        "  zero_duals = np.isclose(duals, 0).astype(np.int)\n",
        "  is_sv = (zero_duals.sum(axis=0)\u003c=1).astype(np.int)\n",
        "  total_sv.append(is_sv.sum())\n",
        "print(\"Total Support Vectors: {}\".format(np.mean(total_sv)))"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "2MBVoJ76puSa"
      },
      "outputs": [],
      "source": [
        "# linear\n",
        "print(\"Total Samples: {}\".format(trn_ct))\n",
        "total_sv = []\n",
        "for _ in range(5):\n",
        "  fm_trn_inds = np.random.choice(trn_x.shape[0], trn_ct, replace=False)\n",
        "  fm_trn_x, fm_trn_y = trn_x[fm_trn_inds], trn_y[fm_trn_inds]\n",
        "\n",
        "  clean_poly = svm.SVC(kernel='poly')\n",
        "  clean_poly.fit(fm_trn_x, fm_trn_y)\n",
        "  duals = np.array(clean_poly.dual_coef_)\n",
        "  zero_duals = np.isclose(duals, 0).astype(np.int)\n",
        "  is_sv = (zero_duals.sum(axis=0)\u003c=1).astype(np.int)\n",
        "  total_sv.append(is_sv.sum())\n",
        "print(\"Total Support Vectors: {}\".format(np.mean(total_sv)))"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "jpy7-tpvpwRq"
      },
      "source": [
        "# FMNIST poison"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "kcMDtqUBp1bG"
      },
      "outputs": [],
      "source": [
        "# linear\n",
        "\n",
        "print(\"Total Samples: {}\".format(trn_ct))\n",
        "total_sv = []\n",
        "for _ in range(5):\n",
        "  fm_inds = np.random.choice(trn_x.shape[0], trn_ct+pois_ct, replace=False)\n",
        "  fm_trn_x, fm_trn_y = trn_x[fm_inds[:trn_ct]], trn_y[fm_inds[:trn_ct]]\n",
        "  fm_pois_x = trn_x[fm_inds[trn_ct:]]\n",
        "  fm_pois_y = 1-trn_y[fm_inds[trn_ct:]]\n",
        "  fm_poised_x = np.concatenate((fm_trn_x, fm_pois_x))\n",
        "  fm_poised_y = np.concatenate((fm_trn_y, fm_pois_y))\n",
        "  pois_linear = svm.SVC(kernel='linear')\n",
        "  pois_linear.fit(fm_poised_x, fm_poised_y)\n",
        "  trn_support_inds = np.where(pois_linear.support_\u003ctrn_ct)[0]\n",
        "  duals = np.array(pois_linear.dual_coef_[:, trn_support_inds])\n",
        "  zero_duals = np.isclose(duals, 0).astype(np.int)\n",
        "  is_sv = (zero_duals.sum(axis=0)\u003c=1).astype(np.int)\n",
        "  total_sv.append(is_sv.sum())\n",
        "print(\"Total Support Vectors: {}\".format(np.mean(total_sv)))"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "ROz6NphhqJy5"
      },
      "outputs": [],
      "source": [
        "# poly\n",
        "print(\"Total Samples: {}\".format(fm_trn_x.shape[0]))\n",
        "total_sv = []\n",
        "for _ in range(5):\n",
        "  fm_inds = np.random.choice(trn_x.shape[0], trn_ct+pois_ct, replace=False)\n",
        "  fm_trn_x, fm_trn_y = trn_x[fm_inds[:trn_ct]], trn_y[fm_inds[:trn_ct]]\n",
        "  fm_pois_x = trn_x[fm_inds[trn_ct:]]\n",
        "  fm_pois_y = 1-trn_y[fm_inds[trn_ct:]]\n",
        "  fm_poised_x = np.concatenate((fm_trn_x, fm_pois_x))\n",
        "  fm_poised_y = np.concatenate((fm_trn_y, fm_pois_y))\n",
        "\n",
        "  pois_poly = svm.SVC(kernel='poly')\n",
        "  pois_poly.fit(fm_poised_x, fm_poised_y)\n",
        "  trn_support_inds = np.where(pois_poly.support_\u003cfm_trn_x.shape[0])[0]\n",
        "  duals = np.array(pois_poly.dual_coef_[:, trn_support_inds])\n",
        "  zero_duals = np.isclose(duals, 0).astype(np.int)\n",
        "  is_sv = (zero_duals.sum(axis=0)\u003c=1).astype(np.int)\n",
        "  total_sv.append(is_sv.sum())\n",
        "print(\"Total Support Vectors: {}\".format(np.mean(total_sv)))"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "4_h5EmoZq8Nm"
      },
      "outputs": [],
      "source": [
        "trn_ct, pois_ct = 1000, 1 \n",
        "fm_inds = np.random.choice(trn_x.shape[0], trn_ct+1, replace=False)\n",
        "fm_trn_x, fm_trn_y = trn_x[fm_inds[:trn_ct]], trn_y[fm_inds[:trn_ct]]\n",
        "targ_x, targ_y = trn_x[fm_inds[trn_ct:trn_ct+1]], trn_y[fm_inds[trn_ct:trn_ct+1]]\n",
        "pois_x, pois_y = np.concatenate([targ_x.copy() for _ in range(pois_ct)]), np.ones(pois_ct)-targ_y\n",
        "print(fm_trn_x.shape, fm_trn_y.shape, targ_x.shape, targ_y.shape, pois_x.shape, pois_y.shape)\n",
        "\n",
        "clean_svm = svm.SVC(kernel='linear')\n",
        "clean_svm.fit(fm_trn_x, fm_trn_y)\n",
        "\n",
        "in_x, in_y = np.concatenate([targ_x, fm_trn_x]), np.concatenate([targ_y, fm_trn_y])\n",
        "in_svm = svm.SVC(kernel='linear')\n",
        "in_svm.fit(in_x, in_y)\n",
        "print(in_svm.support_)\n",
        "\n",
        "poised_x, poised_y = np.concatenate([pois_x, fm_trn_x]), np.concatenate([pois_y, fm_trn_y])\n",
        "poised_inx, poised_iny = np.concatenate([targ_x, pois_x, fm_trn_x]), np.concatenate([targ_y, pois_y, fm_trn_y])\n",
        "\n",
        "p_svm = svm.SVC(kernel='linear')\n",
        "p_svm.fit(poised_x, poised_y)\n",
        "print(p_svm.support_)\n",
        "\n",
        "pin_svm = svm.SVC(kernel='linear')\n",
        "pin_svm.fit(poised_inx, poised_iny)\n",
        "print(pin_svm.support_)\n",
        "\n",
        "\n",
        "def poison(model, target_x, target_y):\n",
        "  pass"
      ]
    }
  ],
  "metadata": {
    "colab": {
      "collapsed_sections": [],
      "name": "svm_pois_mi.ipynb",
      "provenance": []
    },
    "kernelspec": {
      "display_name": "Python 3",
      "name": "python3"
    },
    "language_info": {
      "name": "python"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}
